using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;

namespace Admin.Domain.Entities;

public class User : EntityBase
{
    public User()
    {
        
    }
    /// <summary>
    /// 用户名
    /// </summary>
    public string UserName { get; private set; } = null!;
    /// <summary>
    /// 密码哈希
    /// </summary>
    public string PasswordHash { get; set; } = null!;

    /// <summary>
    /// 密码盐
    /// </summary>
    public string PasswordSalt { get; set; } = null!;

    /// <summary>
    /// 所属部门Id  
    /// </summary>
    public Guid? DepartmentId { get; set; }

    /// <summary>
    /// 最后登录时间
    /// </summary>
    public DateTime? LastLoginTime { get; set; }

    /// <summary>
    /// 角色集合
    /// </summary>
    public virtual ICollection<Role> Roles { get; set; } = new HashSet<Role>();

    /// <summary>
    /// 私有的构造函数
    /// </summary>
    private User(string userName, string passwordHash, string passwordSalt)
    {
        UserName = userName;
        PasswordHash = passwordHash;
        PasswordSalt = passwordSalt;
    }

    /// <summary>
    /// 注册新用户
    /// </summary>
    /// <param name="userName">用户名</param>
    /// <param name="password">密码</param>
    /// <returns>用户对象 或 null</returns>
    public static User? CreateUser(string username, string password)
    {
        if (!ValidateUserName(username) || !ValidatePassword(password))
        {
            return null;
        }
        string salt = GenerateSalt();
        string newpassword = HashPassword(password, salt);

        return new User(username, newpassword, salt);
    }

    /// <summary>
    /// 软删除用户
    /// </summary>
    /// <returns>是否删除成功</returns>
    public bool DeleteUser()
    {
        if (IsDeleted)
        {
            return false;
        }
        IsDeleted = true;
        return true;
    }

    /// <summary>
    /// 更新用户信息
    /// </summary>
    /// <param name="newUserName">新的用户名</param>
    /// <param name="newDescription">新的简介</param>
    /// <returns>是否修改成功</returns>
    public bool UpdateUserInfo(string newUserName, string? newDescription)
    {
        // 验证新的用户名是否有效
        if (!ValidateUserName(newUserName))
        {
            return false;
        }

        // 检查用户是否已经被软删除
        if (IsDeleted)
        {
            return false;
        }

        // 更新用户名
        UserName = newUserName;
        Description = newDescription;
        UpdatedAt = DateTime.UtcNow;
        // 返回更新成功
        return true;
    }

    /// <summary>
    /// 更新用户密码
    /// </summary>
    /// <param name="newPassword">新的密码</param>
    /// <returns>是否更新成功</returns>
    public bool UpdateUserPwd(string newPassword)
    {
        // 验证新的用户名是否有效
        if (!ValidatePassword(newPassword))
        {
            return false;
        }

        // 检查用户是否已经被软删除
        if (IsDeleted)
        {
            return false;
        }

        PasswordSalt = GenerateSalt();
        PasswordHash = HashPassword(newPassword, PasswordSalt);

        // 返回更新成功
        return true;
    }

    /// <summary>
    /// 启用用户
    /// </summary>
    /// <returns>是否启用成功</returns>
    public bool EnableUser()
    {
        // 检查用户是否已经被软删除
        if (IsDeleted)
        {
            return false;
        }

        // 检查用户是否已经被启用
        if (IsActive)
        {
            return false;
        }

        IsActive = true;

        // 返回成功
        return true;
    }

    /// <summary>
    /// 禁用用户
    /// </summary>
    /// <returns>是否禁用成功</returns>
    public bool DisableUser()
    {
        // 检查用户是否已经被软删除
        if (IsDeleted)
        {
            return false;
        }

        // 检查用户是否已经被禁用
        if (!IsActive)
        {
            return false;
        }

        IsActive = false;

        // 返回成功
        return true;
    }

    /// <summary>
    /// 更新用户部门
    /// </summary>
    /// <param name="newDepartmentId">新的部门Id</param>
    /// <returns>是否更新成功</returns>
    public bool UpdateUserDepartment(Guid? newDepartmentId)
    {
        // 检查用户是否已经被软删除
        if (IsDeleted)
        {
            return false;
        }
        DepartmentId = newDepartmentId;
        return true;
    }

    /// <summary>
    /// 赋予角色
    /// </summary>
    /// <param name="role">赋予的角色</param>
    /// <returns>是否赋予成功</returns>
    public bool AssignRole(Role role)
    {
        // 检查用户是否已经被软删除
        if (IsDeleted)
        {
            return false;
        }

        Roles.Add(role);
        return true;
    }

    /// <summary>
    /// 移除角色
    /// </summary>
    /// <param name="role">移除的角色</param>
    /// <returns>是否移除成功</returns>
    public bool RemoveRole(Role role)
    {
        // 检查用户是否已经被软删除
        if (IsDeleted)
        {
            return false;
        }

        Roles.Remove(role);
        return true;
    }

    /// <summary>
    /// 生成密码盐
    /// </summary>
    /// <returns>密码盐</returns>
    private static string GenerateSalt()
    {
        const int SaltSize = 16;
        using RandomNumberGenerator rng = RandomNumberGenerator.Create();
        byte[] salt = new byte[SaltSize];
        rng.GetBytes(salt);
        return Convert.ToHexStringLower(salt);
    }

    /// <summary>
    /// 加密密码
    /// </summary>
    /// <param name="password">密码</param>
    /// <param name="salt">密码盐</param>
    /// <returns>加密后的密码</returns>
    private static string HashPassword(string password, string salt)
    {
        using var algorithm = new Rfc2898DeriveBytes(password, Convert.FromHexString(salt), 10000, HashAlgorithmName.SHA256);
        byte[] passwordHash = algorithm.GetBytes(20);
        return Convert.ToHexStringLower(passwordHash);
    }

    /// <summary>
    /// 验证用户名
    /// </summary>
    /// <param name="userName">用户名</param>
    private static bool ValidateUserName(string username)
    {
        // 验证用户名是否为空
        if (string.IsNullOrWhiteSpace(username))
        {
            return false;
        }

        // 可以添加其他验证

        return true;
    }

    /// <summary>
    /// 验证密码
    /// </summary>
    /// <param name="password">密码</param>
    private static bool ValidatePassword(string password)
    {
        if (string.IsNullOrEmpty(password))
        {
            return false;
        }

        // 可以添加其他验证

        return true;
    }

    /// <summary>
    /// 密码登录验证
    /// </summary>
    /// <param name="salt">密码盐</param>
    /// <param name="password">用户输入密码</param>
    /// <param name="hashedPassword">哈希密码</param>
    public static bool VerifyPasswordHash(string salt, string password, string hashedPassword)
    {
        string newHash = HashPassword(password, salt);
        return newHash.Equals(hashedPassword, StringComparison.OrdinalIgnoreCase);
    }
}
